home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / trilib.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  5.1 KB  |  211 lines

  1. //
  2. // trilib.c: library for loading triangles from an Alias triangle file
  3. //
  4.  
  5. #include <stdio.h>
  6. #include "cmdlib.h"
  7. #include "mathlib.h"
  8. #include "polyset.h"
  9. #include "trilib.h"
  10.  
  11. // on disk representation of a face
  12.  
  13.  
  14. #define    FLOAT_START    99999.0
  15. #define    FLOAT_END    -FLOAT_START
  16. #define MAGIC       123322
  17.  
  18. //#define NOISY 1
  19.  
  20. typedef struct {
  21.     float v[3];
  22. } vector;
  23.  
  24. typedef struct
  25. {
  26.     vector n;    /* normal */
  27.     vector p;    /* point */
  28.     vector c;    /* color */
  29.     float  u;    /* u */
  30.     float  v;    /* v */
  31. } aliaspoint_t;
  32.  
  33. typedef struct {
  34.     aliaspoint_t    pt[3];
  35. } tf_triangle;
  36.  
  37.  
  38. static void ByteSwapTri (tf_triangle *tri)
  39. {
  40.     int        i;
  41.     
  42.     for (i=0 ; i<sizeof(tf_triangle)/4 ; i++)
  43.     {
  44.         ((int *)tri)[i] = BigLong (((int *)tri)[i]);
  45.     }
  46. }
  47.  
  48. static void ReadPolysetGeometry( triangle_t *tripool, FILE *input, int count, triangle_t *ptri )
  49. {
  50.     tf_triangle tri;
  51.     int i;
  52.  
  53.     for (i = 0; i < count; ++i) {
  54.         int        j;
  55.  
  56.         fread( &tri, sizeof(tf_triangle), 1, input );
  57.         ByteSwapTri (&tri);
  58.         for (j=0 ; j<3 ; j++)
  59.         {
  60.             int        k;
  61.  
  62.             for (k=0 ; k<3 ; k++)
  63.             {
  64.                 ptri->verts[j][k] = tri.pt[j].p.v[k];
  65.                 ptri->normals[j][k] = tri.pt[j].n.v[k];
  66. //                ptri->colors[j][k] = tri.pt[j].c.v[k];
  67.             }
  68.  
  69.             ptri->texcoords[j][0] = tri.pt[j].u;
  70.             ptri->texcoords[j][1] = tri.pt[j].v;
  71.         }
  72.  
  73.         ptri++;
  74.         if ((ptri - tripool ) >= POLYSET_MAXTRIANGLES)
  75.             Error ("Error: too many triangles; increase POLYSET_MAXTRIANGLES\n");
  76.     }
  77. }
  78.  
  79. void TRI_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets )
  80. {
  81.     FILE        *input;
  82.     float       start;
  83.     char        name[256], tex[256];
  84.     int         i, count, magic, pset = 0;
  85.     triangle_t    *ptri;
  86.     polyset_t    *pPSET;
  87.     int            iLevel;
  88.     int            exitpattern;
  89.     float        t;
  90.  
  91.     t = -FLOAT_START;
  92.     *((unsigned char *)&exitpattern + 0) = *((unsigned char *)&t + 3);
  93.     *((unsigned char *)&exitpattern + 1) = *((unsigned char *)&t + 2);
  94.     *((unsigned char *)&exitpattern + 2) = *((unsigned char *)&t + 1);
  95.     *((unsigned char *)&exitpattern + 3) = *((unsigned char *)&t + 0);
  96.  
  97.     if ((input = fopen(filename, "rb")) == 0)
  98.         Error ("reader: could not open file '%s'", filename);
  99.  
  100.     iLevel = 0;
  101.  
  102.     fread(&magic, sizeof(int), 1, input);
  103.     if (BigLong(magic) != MAGIC)
  104.         Error ("%s is not a Alias object separated triangle file, magic number is wrong.", filename);
  105.  
  106.     pPSET = calloc( 1, POLYSET_MAXPOLYSETS * sizeof( polyset_t ) );
  107.     ptri = calloc( 1, POLYSET_MAXTRIANGLES * sizeof( triangle_t ) );
  108.  
  109.     *ppPSET = pPSET;
  110.  
  111.     while (feof(input) == 0) {
  112.         if (fread(&start,  sizeof(float), 1, input) < 1)
  113.             break;
  114.         *(int *)&start = BigLong(*(int *)&start);
  115.         if (*(int *)&start != exitpattern)
  116.         {
  117.             if (start == FLOAT_START) {
  118.                 /* Start of an object or group of objects. */
  119.                 i = -1;
  120.                 do {
  121.                     /* There are probably better ways to read a string from */
  122.                     /* a file, but this does allow you to do error checking */
  123.                     /* (which I'm not doing) on a per character basis.      */
  124.                     ++i;
  125.                     fread( &(name[i]), sizeof( char ), 1, input);
  126.                 } while( name[i] != '\0' );
  127.     
  128.                 if ( i != 0 )
  129.                     strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 );
  130.                 else
  131.                     strcpy( pPSET[pset].name , "(unnamed)" );
  132.                 strlwr( pPSET[pset].name );
  133.  
  134. //                indent();
  135. //                fprintf(stdout,"OBJECT START: %s\n",name);
  136.                 fread( &count, sizeof(int), 1, input);
  137.                 count = BigLong(count);
  138.                 ++iLevel;
  139.                 if (count != 0) {
  140. //                    indent();
  141. //                    fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);
  142.     
  143.                     i = -1;
  144.                     do {
  145.                         ++i;
  146.                         fread( &(tex[i]), sizeof( char ), 1, input);
  147.                     } while( tex[i] != '\0' );
  148.  
  149. /*
  150.                     if ( i != 0 )
  151.                         strncpy( pPSET[pset].texname, tex, sizeof( pPSET[pset].texname ) - 1 );
  152.                     else
  153.                         strcpy( pPSET[pset].texname, "(unnamed)" );
  154.                     strlwr( pPSET[pset].texname );
  155. */
  156.  
  157. //                    indent();
  158. //                    fprintf(stdout,"  Object texture name: '%s'\n",tex);
  159.                 }
  160.     
  161.                 /* Else (count == 0) this is the start of a group, and */
  162.                 /* no texture name is present. */
  163.             }
  164.             else if (start == FLOAT_END) {
  165.                 /* End of an object or group. Yes, the name should be */
  166.                 /* obvious from context, but it is in here just to be */
  167.                 /* safe and to provide a little extra information for */
  168.                 /* those who do not wish to write a recursive reader. */
  169.                 /* Mea culpa. */
  170.                 --iLevel;
  171.                 i = -1;
  172.                 do {
  173.                     ++i;
  174.                     fread( &(name[i]), sizeof( char ), 1, input);
  175.                 } while( name[i] != '\0' );
  176.  
  177.                 if ( i != 0 )
  178.                     strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 );
  179.                 else
  180.                     strcpy( pPSET[pset].name , "(unnamed)" );
  181.  
  182.                 strlwr( pPSET[pset].name );
  183.     
  184. //                indent();
  185. //                fprintf(stdout,"OBJECT END: %s\n",name);
  186.                 continue;
  187.             }
  188.         }
  189.  
  190. //
  191. // read the triangles
  192. //        
  193.         if ( count > 0 )
  194.         {
  195.             pPSET[pset].triangles = ptri;
  196.             ReadPolysetGeometry( pPSET[0].triangles, input, count, ptri );
  197.             ptri += count;
  198.             pPSET[pset].numtriangles = count;
  199.             if ( ++pset >= POLYSET_MAXPOLYSETS )
  200.             {
  201.                 Error ("Error: too many polysets; increase POLYSET_MAXPOLYSETS\n");
  202.             }
  203.         }
  204.     }
  205.  
  206.     *numpsets = pset;
  207.  
  208.     fclose (input);
  209. }
  210.  
  211.